package com.sdy.dcsb.web.config;

import com.sdy.dcsb.web.filter.AjaxFilter;
import com.sdy.dcsb.web.interceptor.BizInterceptor;
import com.sdy.common.utils.DateUtil;
import org.apache.catalina.Context;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.webresources.StandardRoot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.Filter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Date;

/**
 * Created by zzq on 2019/1/24.
 */
@Configuration
//@EnableSpringDataWebSupport // 支持controller参数通过主键绑定数据库对象(通过findById)
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private BizInterceptor bizInterceptor;
    @Autowired
    private AjaxFilter ajaxFilter;

    /**
     * 一些web配置
     *
     * @return
     */
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        /**
         * 添加拦截器
         */
        return new WebMvcConfigurer() {
            /**
             * 拦截器配置
             * @param registry
             */
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(bizInterceptor)
                        .addPathPatterns("/**")
                        .excludePathPatterns("/opt/file/**", "/js/**", "/css/**")
                        .order(31);
            }

            /**
             * CORS跨域配置
             * @param registry
             */
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("*")
                        .allowCredentials(true)
                        .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH");
            }

            /**
             * 静态资源配置
             * @param registry
             */
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/static/**", "/opt/file/**")
                        .addResourceLocations("classpath:/webapp/public/static/", "file:/opt/file/");
            }
        };
    }

    /**
     * 表单String字段转Date
     *
     * @return
     */
    @Bean
    public Converter<String, Date> dateConvert() {
        return new Converter<String, Date>() {
            @Override
            public Date convert(String s) {
                //转换日期
                if (s.length() == 19) {
                    return DateUtil.getDate(s, DateUtil.DATETIME_FORMAT);
                } else if (s.length() == 10) {
                    return DateUtil.getDate(s, DateUtil.DATE_FORMAT);
                } else {
                    return null;
                }
            }
        };
    }

    @Bean
    public FilterRegistrationBean filterAjaxRegistration() {
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
        registration.setFilter(ajaxFilter);
        registration.addUrlPatterns("/*");
        registration.setOrder(30);
        return registration;
    }

/*    @Bean
    public ServletRegistrationBean dcsbServletRegistrationBean(ApplicationContext applicationContext) {
        ServletRegistrationBean<TestHttpServlet> s = new ServletRegistrationBean<>(new TestHttpServlet(), "/DCSBWeb/servlet*//*");
        s.setLoadOnStartup(1);
        return s;
    }*/

    @Bean
    public CustomTomcatEmbeddedServletContainerFactory customTomcatEmbeddedServletContainerFactory() {
        return new CustomTomcatEmbeddedServletContainerFactory();
    }

    public static class CustomTomcatEmbeddedServletContainerFactory extends TomcatServletWebServerFactory {
        //在prepareContext中被调用
        @Override
        protected void postProcessContext(Context context) {
            super.postProcessContext(context);
            //添加监听器
            context.addLifecycleListener(event -> {
                if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
                    try {
                        // jar:file:/a.jar!/BOOT-INF/classes!/
                        URL url = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX);
                        String path = "/";

                        String archivePath = null;
                        Class<StandardRoot> clazz = StandardRoot.class;
                        for (Class<?> declaredClass : clazz.getDeclaredClasses()) {
                            if ("BaseLocation".equals(declaredClass.getSimpleName())) {
                                Constructor<?> c = declaredClass.getDeclaredConstructor(URL.class);
                                c.setAccessible(true);
                                Object baseLocation = c.newInstance(url);
                                Method method = declaredClass.getDeclaredMethod("getArchivePath");
                                method.setAccessible(true);
                                archivePath = (String) method.invoke(baseLocation);
                            }
                        }
                        // 当有archivePath时肯定是jar包运行
                        if (archivePath != null) {
                            // url = jar:file:/E:/数动云/郑州DCSB平台/sdy-dcsb/sdy-dcsb-web/target/sdy-dcsb-web-1.0.0-SNAPSHOT.jar!/BOOT-INF/classes!/
                            //archivePath = BOOT-INF/classes!/
                            url = new URL(url.getPath().replace("!/" + archivePath, ""));
                            // url= file:/E:/数动云/郑州DCSB平台/sdy-dcsb/sdy-dcsb-web/target/sdy-dcsb-web-1.0.0-SNAPSHOT.jar
                            // 此时Tomcat再拆分出base = /a.jar archivePath= /
                            path = "/" + archivePath.replace("!/", "");
                            // path = /BOOT-INF/classes
                        }
                        context.getResources().createWebResourceSet(
                                WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/", url, path);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
            });
        }
    }

}
